package com.iqiyi.pps.epg.core.utils;

import java.util.*;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Created with IntelliJ IDEA.
 * User: Qiyi
 * Date: 13-11-11
 * Time: 下午8:49
 */
public class SpeedLimit {

    private static Map<String,SpeedLimit> ALL_SPEED_LIMITOR = new HashMap<String,SpeedLimit>() ;

    private long speedPerSecond = 0L;
    private AtomicLong count = new AtomicLong(0);
    private String uuid = null;
    private String name = null;
    private SpeedLimit(){}//禁止new对象

    static{
        //每秒清空计数器，控制速度
        new Thread(new Runnable(){
            @Override
            public void run() {
                while(true){
                    try {
                        for(SpeedLimit limit : ALL_SPEED_LIMITOR.values()){
                            limit.reset();
                        }
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                }
            }
        }, "SpeedLimit monitor").start();
    }

    /**
     * 速度0或负数，表示停止
     * @param name
     * @param speedPerSecond
     * @return
     */
    public static SpeedLimit newSpeedLimit(String name, long speedPerSecond){
        SpeedLimit speedLimit = new SpeedLimit();
        speedLimit.uuid = UUID.randomUUID().toString();
        speedLimit.speedPerSecond = speedPerSecond;
        speedLimit.name = name;
        ALL_SPEED_LIMITOR.put(speedLimit.uuid, speedLimit);
        return speedLimit;
    }

    /**
     * 控制速度方法，速度超过会等待（不太精准，略有误差）
     */
    public void waitForRun(){
        long num = 0;
        while((num=count.get()) >= speedPerSecond){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
        }
        num = count.incrementAndGet();
    }

    public long getCount() {
        return count.get();
    }

    private void reset(){
        this.count.set(0);
    }

    public void remove(){
        ALL_SPEED_LIMITOR.remove(this.uuid);
    }

    public static boolean setSpeed(String uuid, long speedPerSecond){
        SpeedLimit speedLimit = ALL_SPEED_LIMITOR.get(uuid);
        if(speedLimit == null){
            return false;
        }
        speedLimit.setSpeedPerSecond(speedPerSecond);
        return true;
    }

    public static List<SpeedLimit> getAllSpeedLimit(){
        List<SpeedLimit> list = new ArrayList<SpeedLimit>();
        for(SpeedLimit speedLimit : ALL_SPEED_LIMITOR.values()){
            list.add(speedLimit);
        }
        return list;
    }

    public String getName() {
        return name;
    }

    public String getUuid() {
        return uuid;
    }

    public long getSpeedPerSecond() {
        return speedPerSecond;
    }

    public void setSpeedPerSecond(long speedPerSecond) {
        this.speedPerSecond = speedPerSecond;
    }
}
